<?php

/**
 * MUFFIN
 * News As Nice As Muffins
 * 
 * Simple News System Aimed to easily use in existing sites
 * or projects.
 * 
 * @author		Kozie
 * @version		1.1 beta
 * @copyright 	2008 Kozie Web Solutions
 * @package 	Muffin
 * @subpackage	Smarty
 * 
 */

// Smarty inladen
require_once( 'Smarty.class.php' );


class Muffin
{
	
	/*
	 * De Prevars
	 */
	public $page, 
		   $pcount, 
		   $prevpage, 
		   $nextpage, 
		   $news = array(),
		   $_cfg = array();
					
	private $limit, 
			$db;
					
	private static $_instance, 
				   $_tpl;
	
	
	/**
	 * De init, maakt verbinding met de database en maakt
	 * tevens de singleton instantie aan
	 * 
	 * @param 	$mode		String
	 * @return	$m			Object
	 */
	public static function init( $mode )
	{
		// De classes declareren
		$m = self::instance();
		$s = self::tpl();
		
		// De mappen aangeven
		$s->template_dir	= 'templates/';
		$s->config_dir		= 'configs/';
		$s->compile_dir		= SMARTY_DIR . 'bin/templates_c/';
		$s->cache_dir		= SMARTY_DIR . 'bin/cache/';
		
		//De default configuratie uitlezen
		$s->config_load( 'default.conf', 'general' );
		$m->_cfg = $s->get_config_vars();
		$s->config_load( 'default.conf', 'database' );
		
		// connectie maken met database
		try
		{
			$m->db = new PDO(
				'mysql:host=' . $s->get_config_vars('host') . ';dbname=' . $s->get_config_vars('name') ,
				$s->get_config_vars('user'),
				$s->get_config_vars('pass')
			);
		}
		catch( PDOException $e )
		{
			$s->trigger_error( $e->getMessage(), E_USER_ERROR );
			exit();
		}
		
		// de muffin smartyvars declareren
		$m->assign_muffin_smartyvars();
		
		// Template actie
		switch ($mode)
		{
			// Actie bij het toevoegen van nieuws
			case 'addnews':
				$s->display( 'addnews.tpl' );
				
				if( isset($_POST['doPost']) && $m->setNews($_POST) )
				{
					echo '<script type="text/javascript">closeAndReload();</script>';
				}
				
				break;
				
			// Actie als er ingelogd moet worden
			case 'login':
				// If form is post, go try and login.
				if ( isset($_POST['username']) && isset($_POST['password']) )
				{
					$return = $m->adminLogin();
					
					// Display the template
					if ( !$return )
						$s->display( 'news.tpl' );
					else
						$s->display( 'login.tpl', array('msg'=>$return) );
				}
				else $s->display( 'login.tpl' );
				
				break;
				
			// Actie bij het uitloggen
			case 'logout':
				$m->logout();
				header('Location: index.php');
				
				break;
				
			default:
				$s->display( 'news.tpl' );
				break;
		}
			
		return $m;
	}
	
	
	/**
	 * De singleton functie voor Muffin
	 *
	 * @return Muffin
	 */
	public static function instance()
	{
		$class = __CLASS__;
		
		$return = ( !isset( self::$_instance ) ) ?
			self::$_instance = new $class :
			self::$_instance;
			
		return $return;
	}
	
	
	/**
	 * Singleton functie voor Smarty
	 *
	 * @return Smarty
	 */
	public static function tpl()
	{
		$class = 'Smarty';
		
		$return = ( !isset( self::$_tpl ) ) ?
			self::$_tpl = new $class :
			self::$_tpl;
			
		return $return;
	}
	
	
	/**
	 * Assign Smartyvars die gekoppeld zijn aan Muffin
	 *
	 */
	private function assign_muffin_smartyvars()
	{
		// Declareeer de smarty class
		$s = self::tpl();
		
		// Assign de vars voor template gebruik
		$s->assign( 'template_dir', $s->template_dir );
	}
	
	
	/**
	 * Verkrijg het nieuws en geef terug als arrays in een array
	 *
	 * @param $limit (default 5)
	 * @return arrays in array met alle resultaten; id, titel, auteur, datum, inhoud 
	 */
	public function getNews( $limit = 5 )
	{
		
		// De class declareren
		$m = self::instance();
		
		// Stel de itemlimiet vast
		$m->limit		= $limit;
		
		$page_info		= $m->getPageInfo();
		$start			= $page_info['query_start'];
		
		$query_limit	= ( $limit > 0 ) ? 'LIMIT ' . $start . ',' . $limit : '' ;
		
		// Aanvraag voor nieuws items
		if ( $page_info['item_count'] > 0 ) {
			
			// De query voor het ophalen
			$query 			= 'SELECT *
					  		   FROM news_entries
					  		   ORDER BY id DESC '.
							   $query_limit;
	
			// Haal het nieuws op en plaats het in $this->news als array
			foreach ( $m->db->query( $query ) as $news ) {
				$m->news[] = $news;
			}
		}
		
		else
		{
			// Maak een nep nieuws item aan
			$fake_array = array(
				'id'		=> 0,
				'titel'		=> 'Wat een leegte !',
				'datum'		=> date( 'd-m-Y H:i:s', time() ),
				'auteur'	=> 'Muffin',
				'inhoud'	=> 'Er is geen nieuws item gevonden !'
			);
			
			$m->news[]		= $fake_array;
		}
		
		return $m->news;
	}
	
	
	/**
	 * Functie om de post waardes te checken en te posten als nieuws
	 *
	 * @param array $post
	 * @return string
	 */
	public function setNews( &$post )
	{
		$m = Muffin::instance();
		
		// Check user
		if ( !$m->checkSession() ) exit('Access denied!');
		
		// Check geposte info
		if ( empty( $post['newstitle'] ) || empty( $post['newsbody']))
		{
			//return 'Vul a.u.b. alle velden in';
			return false;
		}
		
		else 
		{
			$query = 'INSERT INTO
					  news_entries
					  	(titel, inhoud, auteur)
					  VALUES
					  	(:titel, :inhoud, \'test\');';
			
			$query = $m->db->prepare( $query );
			
			$query->bindValue( ':titel', $post['newstitle'] );
			$query->bindValue( ':inhoud', $post['newsbody'] );
			
			$query->execute()
				or die( $m->db->errorInfo() );
				
			//return 'Nieuws succesvol toegevoegd !';
			return true;
		}
		
		return false;
	}
	
	
	public function delNews()
	{
		
	}
	
	
	/**
	 * Functie om pagina info te verkrijgen
	 *
	 * @return array met INT waardes; item_count, page_count, current_page, query_start
	 */
	private function getPageInfo()
	{
		
		// De class declareren
		$m = self::instance();
		
		// Tel de huidige aantal records
		$query = 'SELECT COUNT(*)
				  FROM news_entries';
		
		$query = $m->db->query( $query );
		
		$entries = $query->fetchColumn();
		
		// Reken de gewenste waardes uit
		$item_count		= $entries;
		$m->pcount		= ceil( $entries / $m->limit );
		$m->page		= ( isset( $_GET['p'] ) && is_numeric( $_GET['p'] ) ) ? $_GET['p'] : 1 ;
		$query_start	= ( $m->page * $m->limit ) - $m->limit;
		$m->prevpage	= $m->page - 1;
		$m->nextpage	= $m->page + 1;
		
		// Return als een array
		$page_info = array(
			'item_count'	=> $item_count,
			'page_count'	=> $m->pcount,
			'current_page'	=> $m->page,
			'query_start'	=> $query_start
		);
		
		return $page_info;
	}
	
	
	/**
	 * Functie om de aantal pages op te halen en te returnen in een array
	 *
	 * @param $range (default 3)
	 * @return Array met pagina nummers binnen de range
	 */
	public function getPages( $range = 3 )
	{
		// De class declareren
		$m = self::instance();
		
		// Haal de pagina informatie op
		$page_info = $m->getPageInfo();
		
		// Maak een start en een einde voor de range
		$start	= $m->page - $range;
		$end	= $m->page + $range;
		
		// Check of de start geen negatieve waarde is
		if ( $start < 1 ) $start = 1;
			
		// Check of de end var niet boven het aantal paginas zit
		if ( $end > $m->pcount ) $end = $m->pcount;
		
		// Sla de page nummers op in een array
		$pages = array();
		
		for( $i = $start; $i <= $end; $i++ )
		{
			$pages[] = $i;
		}
		
		return $pages;
	}
	
	
	/**
	 * Admin login functie
	 * 
	 * @return Boolean
	 */
	private function adminLogin()
	{
		// Roep een muffin instantie aan
		$m = Muffin::instance();
		
		// Get user and pass
		$user = trim( $_POST['username'] );
		$pass = md5( trim($_POST['password']) );
		
		// Check of de combo goed is
		// Eerst de query uitvoeren
		$query = '	SELECT 	COUNT(*) 
					FROM	users
					WHERE	username="'.$user.'" 
					AND		password="'.$pass.'"';
		
		// Voer de query uit
		$result = $m->db->query( $query );
		
		// Check of de gegevens kloppen
		$count = $result->fetchColumn();
		
		// Check de count
		if ( $count < 1 ) return false;
		
		// Ga anders verder
		else
		{
			// Get vars
			$xuser = $user;
			$xpass = $pass;
			
			// Set session vars
			$_SESSION['xuser'] = $xuser;
			$_SESSION['xpass'] = $xpass;
		}
		
		return true;
	}
	
	
	/**
	 * Logs out admin
	 *
	 */
	private function logout()
	{
		session_destroy();
	}
	
	
	/**
	 * Check session functie
	 * 
	 * Deze functie checkt of de gebruiker goed is ingelogd
	 *
	 * @return Boolean
	 */
	public function checkSession()
	{
		// get muffin
		$m = Muffin::instance();
		
		// Get eerst de session vars
		if		( !isset($_SESSION['xuser']) || !isset($_SESSION['xpass']) ) return false;
		elseif	( empty($_SESSION['xuser']) || empty($_SESSION['xpass']) ) return false;
		
		// Verkrijg de Session vars
		$user = $_SESSION['xuser'];
		$pass = $_SESSION['xpass'];
		
		// Check de database
		$query = '	SELECT 	COUNT(*) 
					FROM	`users` 
					WHERE	username="'.$user.'" 
					AND		password="'.$pass.'"';
		
		// Voer de query uit
		$result = $m->db->query( $query );
		
		// Check of de gegevens kloppen
		$count = $result->fetchColumn();
		
		// Check de count
		if ( $count < 1 ) return false;
			
		// Return true voor einde
		return true;
	}
	
	
	/**
	 * Er mag niet gecloned worden !!!!
	 */
	public function __clone()
	{
		$s = Muffin::tpl();
		
		$s->trigger_error( 'Clone is not allowed!', E_USER_ERROR );
	}
	
}